/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.*;
import me.zhengjie.modules.system.excel.vo.PurchaseRequestDetailVo;
import me.zhengjie.modules.system.repository.*;
import me.zhengjie.modules.system.service.dto.GodownEntryDetailDto;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.system.service.PrePurchaseRequestService;
import me.zhengjie.modules.system.service.dto.PrePurchaseRequestDto;
import me.zhengjie.modules.system.service.dto.PrePurchaseRequestQueryCriteria;
import me.zhengjie.modules.system.service.mapstruct.PrePurchaseRequestMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.stream.Collectors;

import org.springframework.web.multipart.MultipartFile;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author 李忠臻
* @date 2024-03-08
**/
@Service
@RequiredArgsConstructor
public class PrePurchaseRequestServiceImpl implements PrePurchaseRequestService {

    private final PrePurchaseRequestRepository prePurchaseRequestRepository;
    private final PrePurchaseRequestMapper prePurchaseRequestMapper;

    private final PrePurchaseRequestDetailRepository prePurchaseRequestDetailRepository;

    private final PurchaseRequestRepository purchaseRequestRepository;
    private final PurchaseRequestDetailRepository purchaseRequestDetailRepository;

    private final PurchaseDataRepository purchaseDataRepository;

    @Override
    public PageResult<PrePurchaseRequestDto> queryAll(PrePurchaseRequestQueryCriteria criteria, Pageable pageable){
        Page<PrePurchaseRequest> page = prePurchaseRequestRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(prePurchaseRequestMapper::toDto));
    }

    @Override
    public List<PrePurchaseRequestDto> queryAll(PrePurchaseRequestQueryCriteria criteria){
        return prePurchaseRequestMapper.toDto(prePurchaseRequestRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public PrePurchaseRequestDto findById(Long id) {
        PrePurchaseRequest prePurchaseRequest = prePurchaseRequestRepository.findById(id).orElseGet(PrePurchaseRequest::new);
        ValidationUtil.isNull(prePurchaseRequest.getId(),"PrePurchaseRequest","id",id);
        return prePurchaseRequestMapper.toDto(prePurchaseRequest);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(PrePurchaseRequest resources) {
        prePurchaseRequestRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PrePurchaseRequest resources) {
        PrePurchaseRequest prePurchaseRequest = prePurchaseRequestRepository.findById(resources.getId()).orElseGet(PrePurchaseRequest::new);
        ValidationUtil.isNull( prePurchaseRequest.getId(),"PrePurchaseRequest","id",resources.getId());
        prePurchaseRequest.copy(resources);
        prePurchaseRequestRepository.save(prePurchaseRequest);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            prePurchaseRequestRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<PrePurchaseRequestDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (PrePurchaseRequestDto prePurchaseRequest : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("B2B号", prePurchaseRequest.getB2b());
            map.put("文件名", prePurchaseRequest.getFilename());
            map.put("状态（0：未审核,1：已审核 2：已取消）", prePurchaseRequest.getStatus());
            map.put("采购性质", prePurchaseRequest.getPurchaseAttribute());
            map.put("供应商名称", prePurchaseRequest.getSupplierName());
            map.put("审批人", prePurchaseRequest.getAuditBy());
            map.put("审批时间", prePurchaseRequest.getAuditTime());
            map.put("创建者", prePurchaseRequest.getCreateBy());
            map.put("更新者", prePurchaseRequest.getUpdateBy());
            map.put("创建日期", prePurchaseRequest.getCreateTime());
            map.put("更新时间", prePurchaseRequest.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * 直发情况下，审核通过后，采购单状态为已审核，并写入采购数据表，其中入库数等于采购数，在途数为0
     * @param ids
     * @param b2b
     */
    @Transactional
    @Override
    public void pass(List<Long> ids, String b2b) {
        List<PrePurchaseRequest> prePurchaseRequestList = prePurchaseRequestRepository.findAllById(ids);

        Map<String, List<PrePurchaseRequest>> supplierGroupMap = prePurchaseRequestList.stream().
                collect(Collectors.groupingBy(PrePurchaseRequest::getPurchaseAttribute));
        if (supplierGroupMap.size() > 1) {
            throw new BadRequestException("需要选择相同的采购性质，请重新选择");
        }

        if (supplierGroupMap.containsKey("直发") && ids.size() > 1) {
            throw new BadRequestException("直发的情况下只能单选，请重新选择");
        }

        List<PrePurchaseRequestDetail> prePurchaseRequestDetailList = prePurchaseRequestDetailRepository.findByPrePurchaseRequestIdIn(ids);

        PurchaseRequest purchaseRequest = new PurchaseRequest();
        BeanUtils.copyProperties(prePurchaseRequestList.get(0), purchaseRequest);
        purchaseRequest.setId(null);
        purchaseRequest.setB2b(b2b);
//        if (supplierGroupMap.containsKey("直发")) {
        purchaseRequest.setStatus(1);
        purchaseRequest.setAuditTime(new Timestamp(System.currentTimeMillis()));
        purchaseRequest.setAuditBy("system");
        purchaseRequest.setRows(prePurchaseRequestDetailList.size());
//        } else {
//            purchaseRequest.setStatus(0);
//        }
        purchaseRequestRepository.save(purchaseRequest);

        for (PrePurchaseRequest prePurchaseRequest : prePurchaseRequestList) {
            prePurchaseRequest.setB2b(b2b);
            prePurchaseRequest.setStatus(1);
            prePurchaseRequest.setPurchaseRequestId(purchaseRequest.getId());
            prePurchaseRequestRepository.save(prePurchaseRequest);
        }

        for (int i = 0; i < prePurchaseRequestDetailList.size(); i++) {
            PrePurchaseRequestDetail prePurchaseRequestDetail = prePurchaseRequestDetailList.get(i);
            PrePurchaseRequest prePurchaseRequest = prePurchaseRequestRepository.findById(prePurchaseRequestDetail.getPrePurchaseRequestId()).get();
            PurchaseRequestDetail purchaseRequestDetail = new PurchaseRequestDetail();
            prePurchaseRequestDetail.setB2b(b2b);

            BeanUtils.copyProperties(prePurchaseRequestDetail, purchaseRequestDetail);
            purchaseRequestDetail.setId(null);
            purchaseRequestDetail.setPurchaseRequestId(purchaseRequest.getId());
            purchaseRequestDetail.setIndex(i + 1);
            prePurchaseRequestDetailRepository.save(prePurchaseRequestDetail);
            purchaseRequestDetailRepository.save(purchaseRequestDetail);

            if (supplierGroupMap.containsKey("直发")) {
                PurchaseData purchaseData = new PurchaseData();
                BeanUtils.copyProperties(purchaseRequestDetail, purchaseData);
                purchaseData.setId(null);
                purchaseData.setPurchaseRequestId(purchaseRequest.getId());
                purchaseData.setPurchaseRequestDetailId(purchaseRequestDetail.getId());
                purchaseData.setB2b(purchaseRequest.getB2b());
                purchaseData.setGodownQuantity(purchaseRequestDetail.getQuantity());
                purchaseData.setOnPassageQuantity(0);
                purchaseData.setPurchaseAttribute("直发");
                purchaseData.setSupplierName(prePurchaseRequest.getSupplierName());
                purchaseData.setIndex(i + 1);
                purchaseData.setInitBy(prePurchaseRequestDetail.getCreateBy());
                purchaseDataRepository.save(purchaseData);
            } else {
                PurchaseData purchaseData = new PurchaseData();
                BeanUtils.copyProperties(purchaseRequestDetail, purchaseData);
                purchaseData.setId(null);
                purchaseData.setPurchaseRequestId(purchaseRequest.getId());
                purchaseData.setPurchaseRequestDetailId(purchaseRequestDetail.getId());
                purchaseData.setB2b(purchaseRequest.getB2b());
                purchaseData.setGodownQuantity(0);
                purchaseData.setOnPassageQuantity(purchaseRequestDetail.getQuantity());
                purchaseData.setPurchaseAttribute("大货");
                purchaseData.setSupplierName(prePurchaseRequest.getSupplierName());
                purchaseData.setIndex(i + 1);
                purchaseData.setInitBy(prePurchaseRequestDetail.getCreateBy());
                purchaseDataRepository.save(purchaseData);
            }
        }
    }

    @Override
    public void cancel(Long id) {
        PrePurchaseRequest prePurchaseRequest = prePurchaseRequestRepository.findById(id).orElseGet(PrePurchaseRequest::new);
        ValidationUtil.isNull( prePurchaseRequest.getId(),"PurchaseRequest","id", id);
        prePurchaseRequest.setStatus(2);
        prePurchaseRequest.setAuditBy(SecurityUtils.getCurrentUser().getUsername());
        prePurchaseRequest.setAuditTime(new Timestamp(System.currentTimeMillis()));
        prePurchaseRequestRepository.save(prePurchaseRequest);
    }

    @Transactional
    @Override
    public void upload(String supplierName, String purchaseAttribute, MultipartFile file) {
//校验采购单文件名是否重复
//        List<PrePurchaseRequest> prePurchaseRequestList = prePurchaseRequestRepository.findByFilename(file.getOriginalFilename());
//        if (CollectionUtil.isNotEmpty(prePurchaseRequestList)) {
//            throw new BadRequestException("上传的附件文件名称已经存在，请核实后重新上传");
//        }

        try {
            List<PurchaseRequestDetailVo> l = EasyExcel.read(file.getInputStream(), PurchaseRequestDetailVo.class, null).sheet().doReadSync();
//            Boolean b = l.stream().filter(s -> s.getB2b() == null || "".equals(s.getB2b())).findAny().isPresent();
//            if (b) {
//                throw new BadRequestException("存在b2b号为空的数据，请补充后重新上传");
//            }
            PurchaseRequestDetailVo firstPurchaseRequestDetailVo = l.get(0);
            PrePurchaseRequest prePurchaseRequest = new PrePurchaseRequest();
            prePurchaseRequest.setB2b(firstPurchaseRequestDetailVo.getB2b());
            prePurchaseRequest.setStatus(0);
            prePurchaseRequest.setPurchaseAttribute(purchaseAttribute);
            prePurchaseRequest.setSupplierName(supplierName);
            prePurchaseRequest.setFilename(file.getOriginalFilename());
            prePurchaseRequestRepository.save(prePurchaseRequest);

            for (int i = 0; i < l.size(); i++) {
                PurchaseRequestDetailVo purchaseRequestDetailVo = l.get(i);
                PrePurchaseRequestDetail prePurchaseRequestDetail = new PrePurchaseRequestDetail();
                BeanUtils.copyProperties(purchaseRequestDetailVo, prePurchaseRequestDetail);
                prePurchaseRequestDetail.setIndex(i + 1);
                prePurchaseRequestDetail.setStatus(1);
                prePurchaseRequestDetail.setPrePurchaseRequestId(prePurchaseRequest.getId());
                prePurchaseRequestDetail.setExpectedDeliveryDate(purchaseRequestDetailVo.getExpectedDeliveryDate());
                prePurchaseRequestDetailRepository.save(prePurchaseRequestDetail);
            }

        } catch (IOException e) {
            e.printStackTrace();
            throw new BadRequestException(e.getMessage());
        }
    }
}